﻿using System;

namespace T4UtilityBelt.UxDesigns
{
    public static class RendererHelper
    {

        public static TRenderer CreateRenderer<TRenderer>(Platforms platform)
            where TRenderer : class 
        {
            Type t = GetTypeByPlatform<TRenderer>(platform);

            if (t == null)
            {
                throw new RenderException(string.Format("Renderer not found for type {0}, {1}", typeof(TRenderer).Name, platform.ToString()) );
            }

            return Activator.CreateInstance(t) as TRenderer;
        }

        private static Type GetTypeByPlatform<TRenderer>(Platforms platform)
        {
            switch (platform)
            {
                case Platforms.AndroidPhone:
                    return GetTypeByPlatform<TRenderer>(platform, Platforms.Android, Platforms.AndroidTablet);
                case Platforms.AndroidTablet:
                    return GetTypeByPlatform<TRenderer>(platform, Platforms.Android, Platforms.AndroidPhone);

                case Platforms.IosPhone:
                    return GetTypeByPlatform<TRenderer>(platform, Platforms.Ios, Platforms.IosTablet);
                case Platforms.IosTablet:
                    return GetTypeByPlatform<TRenderer>(platform, Platforms.Ios, Platforms.IosPhone);

                case Platforms.WindowsPhone:
                    return GetTypeByPlatform<TRenderer>(platform, Platforms.Windows, Platforms.WindowsTablet, Platforms.Wpf);
                case Platforms.WindowsTablet:
                    return GetTypeByPlatform<TRenderer>(platform, Platforms.Windows, Platforms.WindowsPhone, Platforms.Wpf);
                case Platforms.Wpf:
                    return GetTypeByPlatform<TRenderer>(platform, Platforms.Windows, Platforms.WindowsTablet, Platforms.WindowsPhone);

                case Platforms.ViewModel:
                    return GetTypeByPlatform<TRenderer>(platform, Platforms.ViewModel);
            }
            return null;
        }

        private static Type GetTypeByPlatform<TRenderer>(Platforms platform, Platforms fallback, Platforms fallback2, Platforms fallback3)
        {

            Type t = GetTypeByPlatform<TRenderer>(platform, fallback, fallback2);
            if (t == null)
            {
                return GetType<TRenderer>(fallback3);
            }
            return t;
        }

        private static Type GetTypeByPlatform<TRenderer>(Platforms platform, Platforms fallback, Platforms fallback2)
        {

            Type t = GetTypeByPlatform<TRenderer>(platform, fallback);
            if (t == null)
            {
                return GetType<TRenderer>(fallback2);
            }
            return t;
        }

        private static Type GetTypeByPlatform<TRenderer>(Platforms platform, Platforms fallback)
        {
            Type t = GetType<TRenderer>(platform);
            if (t == null)
            {
                return GetType<TRenderer>(fallback);
            }
            return t;
        }

        private static Type GetType<TRenderer>(Platforms platform)
        {
            Type t = typeof(TRenderer);

            if (t.IsInterface)
            {
                return Type.GetType(t.Namespace + "." + GetNamespacePerPlatform(platform) + "." + t.Name.Substring(1));
            }
            return t;
        }

        private static string GetNamespacePerPlatform(Platforms platform)
        {
            switch (platform)
            {
                case Platforms.Android:
                    return "Android";
                case Platforms.AndroidPhone:
                    return "AndroidPhone";
                case Platforms.AndroidTablet:
                    return "AndroidTablet";
                case Platforms.Common:
                    return "Common";
                case Platforms.Ios:
                    return "Ios";
                case Platforms.IosPhone:
                    return "IosPhone";
                case Platforms.IosTablet:
                    return "IosTablet";
                case Platforms.Windows:
                    return "Windows";
                case Platforms.WindowsPhone:
                    return "WindowsPhone";
                case Platforms.WindowsTablet:
                    return "WindowsTablet";
                case Platforms.Wpf:
                    return "Wpf";
                case Platforms.ViewModel:
                    return "ViewModel";
            }
            return "Common";
        }

    }
}
